﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Xml;

namespace FrontEnd.Storage
{
    ///-------------------------------------------------------------------------------------------------
    /// <summary> Used to save and load front end settings. </summary>
    ///-------------------------------------------------------------------------------------------------
    public class FrontEndStg
    {
        #region Xml Constants

        private const String ROOT_NODE = "Settings";
        private const String EMULATORS_PARENT_NODE = "Emulators";
        private const String EMULATOR_NODE = "Emulator";

        #endregion

        #region Properties

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Gets or sets the emulators. </summary>
        /// <value> The emulators. </value>
        ///-------------------------------------------------------------------------------------------------
        public List<Emulator> Emulators { get; private set; }

        #endregion

        #region Constructor(s)

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Default constructor. </summary>
        ///-------------------------------------------------------------------------------------------------
        public FrontEndStg()
        {
            Init();
            Clear();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Constructor. </summary>
        /// <param name="filePath"> The file to load from. </param>
        ///-------------------------------------------------------------------------------------------------
        public FrontEndStg(String filePath)
        {
            Init();
            LoadFrom(filePath);
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Initialises this object. </summary>
        ///-------------------------------------------------------------------------------------------------
        private void Init()
        {
            Emulators = new List<Emulator>();
        }

        #endregion

        #region Public

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Clears this object to its blank/initial state. </summary>
        ///-------------------------------------------------------------------------------------------------
        public void Clear()
        {
            Emulators.Clear();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Loads from the specified file. </summary>
        /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception>
        /// <exception cref="FileNotFoundException"> Thrown when the requested file is not present. </exception>
        /// <param name="filePath"> The file to load from. </param>
        ///-------------------------------------------------------------------------------------------------
        public void LoadFrom(String filePath)
        {
            if (filePath == null)
                throw new ArgumentNullException("filePath");

            if (!File.Exists(filePath))
                throw new FileNotFoundException("Settings file not found.", filePath);

            // Load file into xml document.
            XmlDocument document = new XmlDocument();
            using (StreamReader sr = new StreamReader(filePath))
                document.Load(sr);

            // Root.
            XmlNode rootNode = document.SelectSingleNode(ROOT_NODE);

            // Emulators.
            Emulators.Clear();
            foreach (XmlNode emulatorNode in rootNode.SelectSingleNode(EMULATORS_PARENT_NODE).SelectNodes(EMULATOR_NODE))
                Emulators.Add(new Emulator(emulatorNode));
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Saves to the specified file. </summary>
        /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception>
        /// <param name="filePath"> The file to save to. </param>
        ///-------------------------------------------------------------------------------------------------
        public void SaveTo(String filePath)
        {
            if (filePath == null)
                throw new ArgumentNullException("filePath");

            // Document and root.
            XmlDocument document = new XmlDocument();
            XmlNode rootNode = document.CreateElement(ROOT_NODE);
            document.AppendChild(rootNode);

            // Emulators parent.
            XmlNode emulatorsParentNode = document.CreateElement(EMULATORS_PARENT_NODE);
            rootNode.AppendChild(emulatorsParentNode);

            // Emulators.
            foreach (Emulator emulator in Emulators)
            {
                XmlNode emulatorNode = document.CreateElement(EMULATOR_NODE);
                emulator.SaveTo(emulatorNode);
                emulatorsParentNode.AppendChild(emulatorNode);
            }

            // Save file.
            using (StreamWriter sw = new StreamWriter(filePath, false, Encoding.UTF8))
                document.Save(sw);
        }

        #endregion

    }
}
